package com.ruicar.afs.cloud.product.controller;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.core.log.annotation.SysLog;
import com.ruicar.afs.cloud.common.core.query.QueryCondition;
import com.ruicar.afs.cloud.common.core.uid.AfsSequenceGenerator;
import com.ruicar.afs.cloud.common.core.util.IResponse;
import com.ruicar.afs.cloud.product.condition.ExtrasProgramCondition;
import com.ruicar.afs.cloud.product.entity.ExtrasProgramInfo;
import com.ruicar.afs.cloud.product.entity.ExtrasProjectProgramInfo;
import com.ruicar.afs.cloud.product.entity.ProductPlan;
import com.ruicar.afs.cloud.product.enums.FitScope;
import com.ruicar.afs.cloud.product.enums.ProductOnlineStatus;
import com.ruicar.afs.cloud.product.enums.StatusEnum;
import com.ruicar.afs.cloud.product.enums.StatusType;
import com.ruicar.afs.cloud.product.service.ExtrasProgramConfigService;
import com.ruicar.afs.cloud.product.service.ExtrasProgramService;
import com.ruicar.afs.cloud.product.service.ProductPlanService;
import com.ruicar.afs.cloud.product.service.ProductRuleInfoService;
import com.ruicar.afs.cloud.product.vo.ExtrasInfoVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.Arrays;
import java.util.List;

/**
 * @author xudongdong
 * @date 2020-05-12
 */
@RestController
@AllArgsConstructor
@RequestMapping("/extrasProgram")
@Api(value = "extrasProgram", description = "附加贷方案信息")
public class ExtrasProgramController {

    private final ExtrasProgramService extrasProgramService;
    private final ExtrasProgramConfigService extrasProgramConfigService;
    private final ProductRuleInfoService ruleInfoService;
    private final ProductPlanService productPlanService;
    private final AfsSequenceGenerator afsSequenceGenerator;

    @PostMapping("/getExtrasProgramListData")
    @ApiOperation(value = "多条件分页获取附加贷方案数据")
    public IResponse<IPage<ExtrasProgramInfo>> getExtrasProgramList(@RequestBody QueryCondition<ExtrasProgramCondition> extrasProgram) {

        return IResponse.success(extrasProgramService.page(new Page(extrasProgram.getPageNumber(), extrasProgram.getPageSize()), Wrappers.<ExtrasProgramInfo>query().lambda()
                .eq(StringUtils.isNotEmpty(extrasProgram.getCondition().getStatus()), ExtrasProgramInfo::getStatus, extrasProgram.getCondition().getStatus())
                .like(StringUtils.isNotEmpty(extrasProgram.getCondition().getPlanNo()), ExtrasProgramInfo::getPlanNo, extrasProgram.getCondition().getPlanNo())
                .like(StringUtils.isNotEmpty(extrasProgram.getCondition().getExtrasPlanName()), ExtrasProgramInfo::getExtrasPlanName, extrasProgram.getCondition().getExtrasPlanName())
                .orderByDesc(ExtrasProgramInfo::getCreateTime)
        ));
    }

    @Transactional
    @PostMapping(value = "/saveOrUpdatePlan")
    @ApiOperation(value = "保存附加贷方案")
    public IResponse<ExtrasProgramInfo> savePlan(@Valid @RequestBody ExtrasProgramInfo extrasProgramInfo) {
        if (extrasProgramInfo.getId() == null) {

            //查询是否有相同编号的方案
            ExtrasProgramInfo extrasProgramInfo1 = extrasProgramService.getOne(Wrappers.<ExtrasProgramInfo>query().lambda()
                            .eq(ExtrasProgramInfo::getExtrasPlanName, extrasProgramInfo.getExtrasPlanName())
                    , false
            );
            if (extrasProgramInfo1 != null) {
                return IResponse.fail("名称重复，请重新填写方案名称！");
            }
            //获取编号
            String planNo = extrasProgramInfo.getPlanNo();
            if(StringUtils.isEmpty(planNo)){
                Long seqno = afsSequenceGenerator.genNext(AfsEnumUtil.key(StatusType.PRODUCT_NUM_FJDFA), StatusType.PRODUCT_NUM_FJDFA.toString());
                planNo = AfsEnumUtil.key(StatusType.PRODUCT_NUM_FJDFA) + DateUtil.year(DateUtil.date()) +StringUtils.leftPad(String.valueOf(seqno), 4, '0');// 编号
                extrasProgramInfo.setPlanNo(planNo);
            }

            extrasProgramInfo.setStatus(AfsEnumUtil.key(StatusEnum.NO));
            extrasProgramService.save(extrasProgramInfo);
        } else {
            extrasProgramService.updateById(extrasProgramInfo);
        }
        return IResponse.success(extrasProgramInfo);
    }

    @Transactional
    @PostMapping(value = "/effectiveExtrasProgram/{ids}")
    @ApiOperation(value = "附加贷方案生效操作")
    public IResponse<Boolean> effectiveByIds(@PathVariable List<Long> ids) {
        for (Long id : ids) {
            ExtrasProgramInfo extrasProgramInfo = extrasProgramService.getById(id);
            if (extrasProgramInfo != null && !AfsEnumUtil.key(StatusEnum.YES).equals(extrasProgramInfo.getStatus())) {
                extrasProgramInfo.setStatus(AfsEnumUtil.key(StatusEnum.YES));
                extrasProgramService.updateById(extrasProgramInfo);
            }
            ruleInfoService.effectiveRule(id, AfsEnumUtil.key(FitScope.EXTRASPLAN),extrasProgramInfo.getExtrasPlanName());
        }
        return new IResponse<Boolean>().setMsg("操作成功");
    }

    @Transactional
    @PostMapping(value = "/invalidExtrasProgram/{ids}")
    @ApiOperation(value = "附加贷方案无效操作")
    public IResponse<Boolean> invalidByIds(@PathVariable List<Long> ids) {
        List<ProductPlan> list = productPlanService.list(Wrappers.<ProductPlan>query().lambda()
                .eq(ProductPlan::getStatus, AfsEnumUtil.key(ProductOnlineStatus.GO_ONLINE))
                .in(ProductPlan::getExtrasPlanId, ids)
        );
        if (list.size() > 0)
            return IResponse.fail("方案被上线产品使用不可设置无效！");
        for (Long id : ids) {
            ExtrasProgramInfo extrasProgramInfo = extrasProgramService.getById(id);
            if (extrasProgramInfo != null && !AfsEnumUtil.key(StatusEnum.NO).equals(extrasProgramInfo.getStatus())) {
                extrasProgramInfo.setStatus(AfsEnumUtil.key(StatusEnum.NO));
                extrasProgramService.updateById(extrasProgramInfo);
            }
            ruleInfoService.invalid(id, AfsEnumUtil.key(FitScope.EXTRASPLAN));
        }
        return new IResponse<Boolean>().setMsg("操作成功");
    }

    @RequestMapping(value = "/deleteById/{id}", method = RequestMethod.DELETE)
    @ApiOperation(value = "通过id删除")
    @Transactional
    @SysLog("删除附加贷方案信息")
    public IResponse<Boolean> delById(@PathVariable String id) {
        ExtrasProgramInfo extrasProgramInfo = extrasProgramService.getById(id);
        if (AfsEnumUtil.key(StatusEnum.YES).equals(extrasProgramInfo.getStatus()))
            return new IResponse<Boolean>().setMsg("方案生效不可删除！");
        List<ProductPlan> list = productPlanService.list(Wrappers.<ProductPlan>query().lambda()
                .eq(ProductPlan::getExtrasPlanId, id)
        );
        if (list.size() > 0) return new IResponse<Boolean>().setMsg("方案被使用不可删除！");
        /**
         * 第一步：删除产品规则信息
         */
        ruleInfoService.delProductRuleInfoList(extrasProgramInfo.getId(), AfsEnumUtil.key(FitScope.EXTRASPLAN));
        /**
         * 第二步：删除附加贷项目信息
         */
        extrasProgramConfigService.remove(Wrappers.<ExtrasProjectProgramInfo>query().lambda().eq(ExtrasProjectProgramInfo::getExtrasPlanId, id));
        /**
         * 第二步：删除方案
         */
        extrasProgramService.removeById(id);
        return new IResponse<Boolean>().setMsg("删除数据成功");
    }

    @PostMapping("/getSelectProjectNames")
    @ApiOperation(value = "获取附加贷项目名称")
    public IResponse<IPage<ExtrasInfoVo>> getSelectProjectNames() {
        List<ExtrasInfoVo> list = extrasProgramService.getSelectProjectNames();
        return IResponse.success(list);
    }

    @RequestMapping(value = "/copyPlan", method = RequestMethod.POST)
    @ApiOperation(value = "产品投放方案复制")
    public IResponse copyPlan(@RequestBody ExtrasProgramInfo plan) {
        //查询是否有相同编号的方案
        ExtrasProgramInfo scheme = extrasProgramService.getOne(Wrappers.<ExtrasProgramInfo>query().lambda()
                        .eq(ExtrasProgramInfo::getExtrasPlanName, plan.getExtrasPlanName())
                , false
        );
        if (scheme != null) {
            return IResponse.fail("名称重复，请重新填写方案名称！");
        }
        //获取编号
        Long seqno = afsSequenceGenerator.genNext(AfsEnumUtil.key(StatusType.PRODUCT_NUM_FJDFA), StatusType.PRODUCT_NUM_FJDFA.toString());
        String planNo = AfsEnumUtil.key(StatusType.PRODUCT_NUM_FJDFA) + DateUtil.year(DateUtil.date()) +StringUtils.leftPad(String.valueOf(seqno), 4, '0');// 编号
        plan.setPlanNo(planNo);
        //原方案ID
        Long oldPlanID = plan.getId();
        //保存方案
        plan.setId(null);
        plan.setStatus(AfsEnumUtil.key(StatusType.INVALID));
        plan.setCreateBy(null);
        plan.setCreateTime(null);
        extrasProgramService.save(plan);
        //新方案ID
        String newPlanID = plan.getId().toString();

        //复制附加项目
        extrasProgramConfigService.copyPlan(oldPlanID, newPlanID);
        //复制规则信息
        ruleInfoService.copyRulePlan(oldPlanID, newPlanID, AfsEnumUtil.key(FitScope.EXTRASPLAN));
        return IResponse.success(plan);
    }


}
